﻿using Commission.Resources;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;

namespace Commission.Models
{
    public class Customer
    {
        [Key]
        public int CustomerID { get; set; }
        
        [Required]
        public string UserName { get; set; }

        [StringLength(100, MinimumLength = 2)]
        [Required(
            ErrorMessageResourceType = typeof(AppResource),
            ErrorMessageResourceName = "ErrorNameIsRequired")]
        public string Name { get; set; }

        [NotMapped]
        public string DisplayName
        {
            get
            {
                return this.UserName + " - " + this.Name;
            }
        }

        [DataType(DataType.Date)]
        public DateTime? BirthDay { get; set; }

        [Required(
            ErrorMessageResourceType = typeof(AppResource),
            ErrorMessageResourceName = "ErrorIDCardIsRequired")]
        [StringLength(12, MinimumLength = 9,
            ErrorMessageResourceType = typeof(AppResource),
            ErrorMessageResourceName = "ErrorIDCardNotCorrect")]
        public string IDCard { get; set; }

        public short Gender { get; set; }

        public string Address { get; set; }

        public string CurrentAddress { get; set; }

        public string PhoneNumber { get; set; }

        [EmailAddress]
        public string Email { get; set; }
                 
        [DataType(DataType.Date)]
        public DateTime AttendantDate { get; set; }

        // khi tạo hội viên thì UpgradeDate = AttendantDate
        [DataType(DataType.Date)]
        public DateTime UpgradeDate { get; set; }

        private DateTime validDate = DateTime.Now;
        [DataType(DataType.Date)]
        public DateTime ValidDate {
            get {
                return validDate;
            }
            set {
                validDate = value;
            }
        }

        public bool IsActive
        {
            get
            {
                if (DateTime.Compare(ValidDate, DateTime.Now) > 0)
                {
                    return true;
                }
                return false;
            }
        }

        public bool IsCanUpgrade
        {
            get
            {
                if (this.CustomerTypeID == (int)CustomerKind.BP
                    || this.CustomerTypeID == (int)CustomerKind.NP
                    || this.CustomerTypeID == (int)CustomerKind.VP
                    || this.CustomerTypeID == (int)CustomerKind.F100
                    || this.CustomerTypeID == (int)CustomerKind.F300
                    || this.CustomerTypeID == (int)CustomerKind.VP150
                    )
                {
                    return true;
                }
                return false;
            }
        }

        public int Position { get; set; }

        [NotMapped]
        public string DisplayPosition { 
            get {
                if (Position == 1) {
                    return " (Trái)";
                } else {
                    return " (Phải)";
                }
            }
        }

        [NotMapped]
        public bool CustomerTypeConfirmed { get; set; }

        [NotMapped]
        public int OldCustomerTypeID { get; set; }

        [Required(
            ErrorMessageResourceType = typeof(AppResource),
            ErrorMessageResourceName = "ErrorCustomerTypeIsRequired")]
        [Range(1, 1000,
            ErrorMessageResourceType = typeof(AppResource),
            ErrorMessageResourceName = "ErrorCustomerTypeIsRequired")]
        public int CustomerTypeID { get; set; }
        public virtual CustomerType CustomerType { get; set; }

        public int? ParentCustomerID { get; set; }
        public virtual Customer ParentCustomer { get; set; }

        public virtual ICollection<Customer> SubCustomers { get; set; }

        private string sponsorUserName;
        [NotMapped]
        public string SponsorUserName {
            get
            {
                if (SponsorCustomer != null)
                {
                    return SponsorCustomer.UserName;
                }
                return sponsorUserName;
            }
            set
            {
                sponsorUserName = value;
            } 
        }

        private string sponsorName;
        [NotMapped]
        public string SponsorName
        {
            get
            {
                if (SponsorCustomer != null)
                {
                    return SponsorCustomer.Name;
                }
                return sponsorName;
            }
            set
            {
                sponsorName = value;
            }
        }

        [NotMapped]
        public bool SponsorConfirmed { get; set; }

        private string parentUserName;
        [NotMapped]
        public string ParentUserName
        {
            get
            {
                if (ParentCustomer != null)
                {
                    return ParentCustomer.UserName;
                }
                return parentUserName;
            }
            set
            {
                parentUserName = value;
            }
        }

        private string parentName;
        [NotMapped]
        public string ParentName
        {
            get
            {
                if (ParentCustomer != null)
                {
                    return ParentCustomer.Name;
                }
                return parentName;
            }
            set
            {
                parentName = value;
            }
        }

        [NotMapped]
        public bool ParentConfirmed { get; set; }

        [NotMapped]
        public decimal Amount20 { get; set; }

        [NotMapped]
        public decimal Amount80 { get; set; }

        public int? SponsorCustomerID { get; set; }
        [ForeignKey("SponsorCustomerID")]
        public virtual Customer SponsorCustomer { get; set; }

        public virtual ICollection<Customer> SponsoredCustomers { get; set; }

        [NotMapped]
        public int DirectCustomerID { get; set; }

        public decimal GetPoint(int position)
        {
            if (this.SubCustomers.Count < 1) return 0;

            Customer subCustomer = this.SubCustomers.FirstOrDefault(x => x.Position == position);

            if (subCustomer == null) return 0;

            return subCustomer.GetPoint();
        }

        private decimal GetPoint()
        {
            //if (customer.SubCustomers.Count < 1) return 0;

            decimal point = this.CustomerType.Point;

            foreach (var subCustomer in this.SubCustomers)
            {
                point = point + subCustomer.GetPoint();
            }

            return point;
        }

        public IList<Customer> GetChilds(int position)
        {
            if (this.SubCustomers.Count < 1) return null;

            Customer subCustomer = this.SubCustomers
                .FirstOrDefault(x => x.Position == position);

            if (subCustomer == null) return null;

            return subCustomer.GetChilds();
        }

        public IList<Customer> GetChilds()
        {
            IList<Customer> list = new List<Customer>();
            list.Add(this);

            foreach (var subCustomer in this.SubCustomers)
            {
                list.AddRange(subCustomer.GetChilds());
            }

            return list;
        }

        public IList<Customer> AllSubCustomers()
        {
            IList<Customer> list = new List<Customer>();

            foreach (var subCustomer in this.SubCustomers)
            {
                list.Add(subCustomer);

                if (subCustomer.SubCustomers != null && subCustomer.SubCustomers.Count > 0)
                {
                    list.AddRange(subCustomer.AllSubCustomers());
                }
            }

            return list;
        }
    }

    public enum CustomerKind
    {
        BP = 1,
        NP = 2,
        VP150 = 3,
        VP = 4,
        AP700 = 5,
        AP = 6,
        F100 = 7,
        F300 = 8,
        F1000 = 9,
    }; 
}